{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import jsonlines\n",
    "from collections import defaultdict\n",
    "import openai\n",
    "import json\n",
    "import regex\n",
    "from typing import Dict, Any, Tuple\n",
    "from tqdm import tqdm \n",
    "\n",
    "import seaborn as sns\n",
    "from matplotlib import pyplot as plt\n",
    "import pickle\n",
    "import pprint"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data = defaultdict(list)\n",
    "test_data = defaultdict(list)\n",
    "\n",
    "for i in range(5):\n",
    "    with jsonlines.open(f'train_{i}.jsonl') as f:\n",
    "        for line in f.iter():\n",
    "            train_data[i].append(line)\n",
    "\n",
    "    with jsonlines.open(f'test_{i}.jsonl') as f:\n",
    "        for line in f.iter():\n",
    "            test_data[i].append(line)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "time_dict = {\n",
    "    'days': 24,\n",
    "    'day': 24,\n",
    "    'weeks': 24*7,\n",
    "    'week': 24*7,\n",
    "    'hours': 1,\n",
    "    'hour': 1,\n",
    "    'h': 1,\n",
    "    'minute': 1/60,\n",
    "    'min': 1/60,\n",
    "    's': 1/3600\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Metric(object):\n",
    "    def __init__(self):\n",
    "        self.n_true = 0\n",
    "        self.n_false = 0\n",
    "        self.tag_true = defaultdict(int)\n",
    "        self.tag_false = defaultdict(int)\n",
    "\n",
    "    def update(self, answer: bool, tag=None):\n",
    "        if answer:\n",
    "            self.n_true += 1\n",
    "            if tag:\n",
    "                self.tag_true[tag] += 1\n",
    "        else:\n",
    "            self.n_false += 1\n",
    "            if tag:\n",
    "                self.tag_false[tag] += 1\n",
    "\n",
    "    def update_list(self, true_list, pred_list, tag=None):\n",
    "        if not isinstance(true_list, list) or not isinstance(pred_list, list):\n",
    "            if true_list == pred_list:\n",
    "                self.n_true += 1\n",
    "                if tag:\n",
    "                    self.tag_true[tag] += 1\n",
    "            else:\n",
    "                self.n_false += 1\n",
    "                if tag:\n",
    "                    self.tag_false[tag] += 1\n",
    "            return \n",
    "\n",
    "        for ls in pred_list:\n",
    "            if ls in true_list:\n",
    "                self.n_true += 1\n",
    "                if tag:\n",
    "                    self.tag_true[tag] += 1\n",
    "            else:\n",
    "                self.n_false += 1\n",
    "                if tag:\n",
    "                    self.tag_false[tag] += 1\n",
    "\n",
    "    def update_temp(self, true, pred):\n",
    "        eps = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]\n",
    "        if not isinstance(true, str) or not isinstance(pred, str):\n",
    "            if true == pred:\n",
    "                self.n_true += 1\n",
    "                self.tag_true['temperature'] += 1\n",
    "                for e in eps:\n",
    "                    self.tag_true[f'temperature-{e}'] += 1\n",
    "\n",
    "            else:\n",
    "                self.n_false += 1\n",
    "                self.tag_false['temperature'] += 1\n",
    "                for e in eps:\n",
    "                    self.tag_false[f'temperature-{e}'] += 1\n",
    "            return\n",
    "\n",
    "        if '°C' not in true or '°C' not in pred:\n",
    "            if true == pred:\n",
    "                self.n_true += 1\n",
    "                self.tag_true['temperature'] += 1\n",
    "                for e in eps:\n",
    "                    self.tag_true[f'temperature-{e}'] += 1\n",
    "\n",
    "            else:\n",
    "                self.n_false += 1\n",
    "                self.tag_false['temperature'] += 1\n",
    "                for e in eps:\n",
    "                    self.tag_false[f'temperature-{e}'] += 1\n",
    "            return\n",
    "\n",
    "        true = float(true.replace('°C', '').strip())\n",
    "        pred = float(pred.replace('°C', '').strip())\n",
    "\n",
    "        if abs(true-pred) <= 10:\n",
    "            self.n_true += 1\n",
    "            self.tag_true['temperature'] += 1\n",
    "        else:\n",
    "            self.n_false += 1\n",
    "            self.tag_false['temperature'] += 1\n",
    "\n",
    "        for e in eps:\n",
    "            if abs(true-pred) <= e:\n",
    "                self.tag_true[f'temperature-{e}'] += 1\n",
    "            else:\n",
    "                self.tag_false[f'temperature-{e}'] += 1\n",
    "\n",
    "    def update_time(self, true, pred):\n",
    "        if not isinstance(true, str) or not isinstance(pred, str):\n",
    "            if true == pred:\n",
    "                self.n_true += 1\n",
    "                self.tag_true['time'] += 1\n",
    "            else:\n",
    "                self.n_false += 1\n",
    "                self.tag_false['time'] += 1\n",
    "            return\n",
    "        \n",
    "        unit_true = regex.search(r\"(?<=\\b|\\d)(days|day|weeks|week|hours|hour|h|minute|min|s)\\b\", str(true))\n",
    "        unit_pred = regex.search(r\"(?<=\\b|\\d)(days|day|weeks|week|hours|hour|h|minute|min|s)\\b\", str(pred))\n",
    "\n",
    "        if not unit_pred or not unit_true:\n",
    "            if true == pred:\n",
    "                self.n_true += 1\n",
    "                self.tag_true['time'] += 1\n",
    "            else:\n",
    "                self.n_false += 1\n",
    "                self.tag_false['time'] += 1\n",
    "            return\n",
    "\n",
    "        times_true = time_dict[unit_true.group()]\n",
    "        times_pred = time_dict[unit_pred.group()]\n",
    "\n",
    "        true = float(true.split()[0]) * times_true + 1e-6\n",
    "        pred = float(pred.split()[0]) * times_pred + 1e-6\n",
    "\n",
    "        if true/pred < 2 and true/pred > 0.5:\n",
    "            self.n_true += 1\n",
    "            self.tag_true['time'] += 1\n",
    "        else:\n",
    "            self.n_false += 1\n",
    "            self.tag_false['time'] += 1\n",
    "        \n",
    "    def update_pressure(self, true: str, pred: str):\n",
    "        if not isinstance(true, str) or not isinstance(pred, str):\n",
    "            if true == pred:\n",
    "                self.n_true += 1\n",
    "                self.tag_true['pressure'] += 1\n",
    "            else:\n",
    "                self.n_false += 1\n",
    "                self.tag_false['pressure'] += 1\n",
    "            return\n",
    "        \n",
    "        if 'atm' not in true or 'atm' not in pred:\n",
    "            if true == pred:\n",
    "                self.n_true += 1\n",
    "                self.tag_true['pressure'] += 1\n",
    "            else:\n",
    "                self.n_false += 1\n",
    "                self.tag_false['pressure'] += 1\n",
    "            return\n",
    "\n",
    "        true = float(true.replace('atm', '').strip())\n",
    "        pred = float(pred.replace('atm', '').strip())\n",
    "\n",
    "        if abs(true-pred) <= 1:\n",
    "            self.n_true += 1\n",
    "            self.tag_true['pressure'] += 1\n",
    "        else:\n",
    "            self.n_false += 1\n",
    "            self.tag_false['pressure'] += 1\n",
    "\n",
    "    def accuracy(self, ):\n",
    "        return self.n_true / (self.n_true + self.n_false)\n",
    "    \n",
    "    def accuracy_task(self, ):\n",
    "        output = dict()\n",
    "        for key in self.tag_true:\n",
    "            n_true = self.tag_true[key]\n",
    "            n_false = self.tag_false[key]\n",
    "            acc = n_true / (n_true + n_false)\n",
    "            output[key] = acc\n",
    "        return output\n",
    "\n",
    "\n",
    "def evaluate(true, prediction, metric: Metric):\n",
    "    if not isinstance(prediction, dict):\n",
    "        metric.update(False)\n",
    "        return\n",
    "    # precursor\n",
    "    try:\n",
    "        metric.update_list(true.get('precursors', None), prediction.get('precursors', None), tag='precursor')\n",
    "    except Exception as e:\n",
    "        metric.update(False, tag='precursor')\n",
    "\n",
    "    # solvent\n",
    "    try:\n",
    "        metric.update_list(true['solvent'], prediction['solvent'], tag='solvent')\n",
    "    except:\n",
    "        metric.update(False, tag='solvent')\n",
    "    \n",
    "    # conditions\n",
    "    metric.update_temp(true.get('temperature', None), prediction.get('temperature', None))\n",
    "    metric.update_time(true.get('time'), prediction.get('time'))\n",
    "\n",
    "    pressure = prediction.get('pressure')\n",
    "    if pressure == 'autogenous pressure':\n",
    "        pressure = 'autogenous'\n",
    "    metric.update_pressure(true.get('pressure'), pressure)\n",
    "\n",
    "    # method\n",
    "    synthesis_method = prediction.get('synthesis_method')\n",
    "    if synthesis_method == 'solvothermal':\n",
    "        synthesis_method = 'solvothermal synthesis'\n",
    "    metric.update(true.get('synthesis_method') == synthesis_method, tag='method')\n",
    "    metric.update(true.get('cooling') == prediction.get('cooling'), tag='method')\n",
    "    metric.update_list(true.get('washing'), prediction.get('washing'), tag='method')\n",
    "    metric.update(true.get('filtration') == prediction.get('filtration'), tag='method')\n",
    "    metric.update(true.get('drying') == prediction.get('drying'), tag='method')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('true_label_save.pickle', 'rb') as f:\n",
    "    true_label = pickle.load(f)\n",
    "\n",
    "with open('prediction_label_save.pickle', 'rb') as f:\n",
    "    prediction_label = pickle.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gpt3.5-0\n",
      "gpt4-0\n"
     ]
    }
   ],
   "source": [
    "result_dict = defaultdict(list)\n",
    "\n",
    "for key in true_label.keys():\n",
    "    true, prediction = true_label[key], prediction_label[key]\n",
    "\n",
    "    print (key)\n",
    "    for t, p in zip(true, prediction):\n",
    "        if t is None or p is None:\n",
    "            continue\n",
    "        metric = Metric()\n",
    "        evaluate(t, p, metric)\n",
    "        result_dict[key].append(metric.accuracy())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.8333333333333334, 0.8333333333333334)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result_dict.keys()\n",
    "import numpy as np\n",
    "np.median(result_dict['gpt3.5-0']), np.median(result_dict['gpt4-0'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('true_label_fewshot_gpt3_save.pickle', 'rb') as f:\n",
    "    true_gpt3 = pickle.load(f)\n",
    "\n",
    "with open('prediction_label_fewshot_gpt3_save.pickle', 'rb') as f:\n",
    "    prediction_gpt3 = pickle.load(f)\n",
    "    \n",
    "for t, p in zip(true_gpt3, prediction_gpt3):\n",
    "    metric = Metric()\n",
    "    evaluate(t, p, metric)\n",
    "    result_dict['gpt-3.5-fewshot'].append(metric.accuracy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('true_label_fewshot100_gpt3_save.pickle', 'rb') as f:\n",
    "    true_gpt3 = pickle.load(f)\n",
    "\n",
    "with open('prediction_label_fewshot100_gpt3_save.pickle', 'rb') as f:\n",
    "    prediction_gpt3 = pickle.load(f)\n",
    "    \n",
    "for t, p in zip(true_gpt3, prediction_gpt3):\n",
    "    metric = Metric()\n",
    "    evaluate(t, p, metric)\n",
    "    result_dict['gpt-3.5-fewshot-100'].append(metric.accuracy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('true_label_zeroshot_gpt3_save.pickle', 'rb') as f:\n",
    "    true_gpt3 = pickle.load(f)\n",
    "\n",
    "with open('prediction_label_zeroshot_gpt3_save.pickle', 'rb') as f:\n",
    "    prediction_gpt3 = pickle.load(f)\n",
    "    \n",
    "for t, p in zip(true_gpt3, prediction_gpt3):\n",
    "    metric = Metric()\n",
    "    evaluate(t, p, metric)\n",
    "    result_dict['gpt-3.5-zeroshot'].append(metric.accuracy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('true_label_fewshot_gpt4o_save.pickle', 'rb') as f:\n",
    "    true_gpt4o = pickle.load(f)\n",
    "\n",
    "with open('prediction_label_fewshot_gpt4o_save.pickle', 'rb') as f:\n",
    "    prediction_gpt4o = pickle.load(f)\n",
    "    \n",
    "for t, p in zip(true_gpt4o, prediction_gpt4o):\n",
    "    metric = Metric()\n",
    "    evaluate(t, p, metric)\n",
    "    result_dict['gpt-4o-fewshot'].append(metric.accuracy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('true_label_zeroshot_gpt4o_save.pickle', 'rb') as f:\n",
    "    true_gpt4o = pickle.load(f)\n",
    "\n",
    "with open('prediction_label_zeroshot_gpt4o_save.pickle', 'rb') as f:\n",
    "    prediction_gpt4o = pickle.load(f)\n",
    "    \n",
    "for t, p in zip(true_gpt4o, prediction_gpt4o):\n",
    "    metric = Metric()\n",
    "    evaluate(t, p, metric)\n",
    "    result_dict['gpt-4o-zeroshot'].append(metric.accuracy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('true_label_fewshot100_gpt4o_save.pickle', 'rb') as f:\n",
    "    true_gpt3 = pickle.load(f)\n",
    "\n",
    "with open('prediction_label_fewshot100_gpt4o_save.pickle', 'rb') as f:\n",
    "    prediction_gpt3 = pickle.load(f)\n",
    "    \n",
    "for t, p in zip(true_gpt3, prediction_gpt3):\n",
    "    metric = Metric()\n",
    "    evaluate(t, p, metric)\n",
    "    result_dict['gpt-4o-fewshot-100'].append(metric.accuracy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('true_label_random_save.pickle', 'rb') as f:\n",
    "    true_random = pickle.load(f)\n",
    "\n",
    "with open('prediction_label_random_save.pickle', 'rb') as f:\n",
    "    prediction_random = pickle.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "for t, p in zip(true_random, prediction_random):\n",
    "    metric = Metric()\n",
    "    evaluate(t, p, metric)\n",
    "    result_dict['random'].append(metric.accuracy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('true_label_random_feq_save.pickle', 'rb') as f:\n",
    "    true_feq_random = pickle.load(f)\n",
    "\n",
    "with open('prediction_label_random_feq_save.pickle', 'rb') as f:\n",
    "    prediction_feq_random = pickle.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "for t, p in zip(true_feq_random, prediction_feq_random):\n",
    "    metric = Metric()\n",
    "    evaluate(t, p, metric)\n",
    "    result_dict['random_feq'].append(metric.accuracy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "name_dict = {\n",
    "    'gpt4-0': 'GPT-4o', \n",
    "    'gpt3.5-0': 'GPT-3.5', \n",
    "    'gpt-4o-zeroshot': 'GPT-4o',\n",
    "    'gpt-3.5-zeroshot': 'GPT-3.5',\n",
    "    'gpt-4o-fewshot': 'GPT-4o', \n",
    "    'gpt-3.5-fewshot': 'GPT-3.5', \n",
    "    'gpt-4o-fewshot-100': 'GPT-4o',\n",
    "    'gpt-3.5-fewshot-100': 'GPT-3.5',\n",
    "    'random': 'Random',\n",
    "    'random_feq': 'Statistic'\n",
    "}\n",
    "\n",
    "color=['#CF796A', '#CF796A', '#658CC8', '#658CC8', '#6AB55F', '#6AB55F', '#C7A663', '#C7A663', '#999999', '#999999']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The PostScript backend does not support transparency; partially transparent artists will be rendered opaque.\n"
     ]
    },
    {
     "data": {
      "image/png": "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fcJkmIjIzLm5uWHv3r3a7YSEBLRr167Scx0cHJCamqrd/vbbb+Ho6GjwGImI6ismw0REZm7UqFHYs2cPAODRo0e4detWlT24o0ePxtdffw3g8dK+EokEjRs3BgDk5ORg4MCBCAwMxEsvvaTtWZ43bx569+6NMWPG4OHDhwCAa9euITg4GFKpFK+88gry8/MNW0kiIhNhMkxEZOY8PDxQWFiI+/fv4/vvv0dQUFCV5wYGBiItLQ1qtRpff/01Ro4cqT32zjvvYMGCBThy5AjeeecdzJkzB6dPn8bZs2fx888/Y/369SgpKQEAzJ07F3PnzoVMJsPrr7+O5cuXG7yeRESmwGSYiKgeGD58OPbu3Ys9e/Zg9OjRVZ4nEong7++P1NRUpKSkYMiQIdpjv/76KwYMGAAACAgIwKVLl5CVlYWePXtCIBDgueeeg7u7OwDg4sWLWLFiBaRSKT766CP88ccfhq0gEZGJMBkmIqoHRo8ejS+//BL379+Hs7NzteeOGTMGMTExaNWqFaytrbX7vby8kJaWBgA4cuQIPDw80LFjR/z000/QaDS4c+cOrl27pj133bp1kMlk+Pjjj/H3v//dcJUjIjIhK1MHQERkif7v//4PvXr10m7LZDIAqLBvzpw52v+3a9cORUVFmDhx4jPL7t+/P8aOHYvPPvuswv41a9bgjTfewPLlyyEQCBAbG4sOHTpgwIAB6N27N9q1a6d92G7NmjWYOnUq5HI5FAoFPvnkk7pUl4jIbAk0Go3G1EEQEREREZkCh0kQERERkcViMkxEREREFovJMBERERFZLCbDRERERGSxmAwTERERkcViMkxEREREFovJMBERERFZLCbDRERERGSxmAwTERERkcViMkxEREREFovJMBERERFZrP8Ht6T/nVR50FAAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 708.662x236.221 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "mm = 0.0393701\n",
    "color=['#CF796A', '#CF796A', '#658CC8', '#658CC8', '#658CC8', '#658CC8', '#658CC8', '#658CC8', '#999999', '#999999']\n",
    "\n",
    "plt.rcParams['font.family'] = 'arial'\n",
    "plt.rcParams['font.size'] = 7\n",
    "\n",
    "#fig, ax = plt.subplots(1, 1, figsize=(115* mm, 60* mm))\n",
    "fig, ax = plt.subplots(1, 1, figsize=(180* mm, 60* mm))\n",
    "\n",
    "for i, key in enumerate(name_dict.keys()):\n",
    "    value = result_dict[key]\n",
    "    sns.boxplot(x=i, y=value, color=color[i], width=0.5, linecolor='#252525', linewidth=0.75, fliersize=1.5)\n",
    "\n",
    "plt.xticks(range(len(name_dict)), name_dict.values())\n",
    "plt.xlabel('LLM Model', fontsize=7)\n",
    "plt.ylabel('Recommendation Score', fontsize=9)\n",
    "\n",
    "plt.legend(['Fine-tuning', 'Prompt engineering', 'Rule-based'], loc='lower right')\n",
    "\n",
    "plt.tight_layout()\n",
    "\n",
    "plt.savefig('llm.eps', bbox_inches='tight')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The PostScript backend does not support transparency; partially transparent artists will be rendered opaque.\n"
     ]
    },
    {
     "data": {
      "image/png": "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we7du7F06VKEhYWhcePGCAoKwi+//ILevXtj3rx52L17N4C7UzN7e3ujb9++8PT0xIwZM6BWqxEWFoYxY8bYRlXx9/fHiy++iP79+wMAJk2aBK1W6/T95HTMREREROS2eJkEEREREbkthmEiIiIiclsMw0RERETkthiGiYiIiMhtMQwTERERkdtiGCYiIiIit8UwTERUxwwGA+Li4u5bXzHD172WLFkCDw+PShMefPnll1AoFLh48WKlx8bFxeGxxx6rNIj95s2bJQ3m/6AaKly8eNGumceIiFwJwzARUT3Xrl077Nmzx7a8Y8cOtG3b9oGP9fHxQUZGhm35888/h5+fn9NrJCJyVQzDRET13MiRI7Fr1y4AwK+//orCwsIqe3BHjRqFTz/9FMDdqX11Oh0aN24MAMjPz8fAgQMxYMAAPPPMM7ae5YULF6JXr14YPXo0bt++DQD48ccfER0dDb1ej9///vcoKSlx7k4SEcmEYZiIqJ4LCgrCtWvXcP36dXzxxReIioqq8rEDBgxAZmYmBEHAp59+ihEjRti2LViwAAkJCThy5AgWLFiA+fPn47vvvsPJkyfxr3/9C2vWrMHNmzcBAPHx8YiPj4fBYMCkSZOwdOlSp+8nEZEcGIaJiFzAsGHDsGfPHuzatQujRo2q8nEqlQrh4eHIyMjAgQMHMHjwYNu2f//73+jfvz8AIDIyEmfPnkVubi569uwJhUKBxx57DIGBgQCAM2fOYNmyZdDr9Xj77bfxyy+/OHcHiYhkwjBMROQCRo0ahU8++QTXr19Hy5Ytq33s6NGjkZycjObNm8PDw8O2vmPHjsjMzAQAHDlyBEFBQejQoQO++eYbiKKIy5cv48cff7Q99p133oHBYMC6devw3HPPOW/niIhkpJa7ACIid/S///u/ePLJJ23LBoMBACqtmz9/vu3fbdu2hdFoxIQJEx7adkREBMaOHYv333+/0vpVq1bhz3/+M5YuXQqFQoHNmzejffv26N+/P3r16oW2bdvabrZbtWoVpk2bBpPJBLPZjL/97W+12V0ionpLIYqiKHcRRERERERy4GUSREREROS2GIaJiIiIyG0xDBMRERGR22IYJiIiIiK3xTBMRERERG6LYZiIiIiI3BbDMBERERG5LYZhIiIiInJbDMNERERE5LYYhomIiIjIbTEMExEREZHb+j/DcND+/GnpdwAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 708.662x236.221 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "mm = 0.0393701\n",
    "color=['#CF796A',  '#658CC8', '#CF796A',  '#658CC8', '#CF796A',  '#658CC8', '#CF796A',  '#658CC8',  '#999999', '#999999']\n",
    "\n",
    "plt.rcParams['font.family'] = 'arial'\n",
    "plt.rcParams['font.size'] = 7\n",
    "\n",
    "# fig, ax = plt.subplots(1, 1, figsize=(115* mm, 60* mm))\n",
    "fig, ax = plt.subplots(1, 1, figsize=(180* mm, 60* mm))\n",
    "\n",
    "for i, key in enumerate(name_dict.keys()):\n",
    "    value = result_dict[key]\n",
    "    sns.boxplot(x=i, y=value, color=color[i], width=0.5, linecolor='#252525', linewidth=0.75, fliersize=1.5)\n",
    "\n",
    "plt.xticks(range(len(name_dict)), name_dict.values())\n",
    "plt.xlabel('LLM Model', fontsize=7)\n",
    "plt.ylabel('Recommendation Score', fontsize=9)\n",
    "plt.legend(['GPT-4o',t 'GPT-3.5'], loc='upper right')\n",
    "plt.tight_layout()\n",
    "\n",
    "plt.savefig('llm2.eps', bbox_inches='tight')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "metric_output = dict()\n",
    "for key in true_label.keys():\n",
    "    true, prediction = true_label[key], prediction_label[key]\n",
    "\n",
    "    metric_task = Metric()\n",
    "    for t, p in zip(true, prediction):\n",
    "        if t is None or p is None:\n",
    "            continue\n",
    "        #metric = Metric()\n",
    "        evaluate(t, p, metric_task)\n",
    "\n",
    "    metric_output[key] = metric_task\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'precursor': 0.9911081837642022,\n",
       " 'solvent': 0.6830559757942511,\n",
       " 'temperature': 0.4933142311365807,\n",
       " 'temperature-10': 0.4933142311365807,\n",
       " 'temperature-20': 0.6150907354345749,\n",
       " 'temperature-30': 0.6528175740210124,\n",
       " 'temperature-40': 0.7263610315186246,\n",
       " 'temperature-50': 0.7483285577841452,\n",
       " 'temperature-60': 0.779847182425979,\n",
       " 'temperature-70': 0.8046800382043935,\n",
       " 'temperature-80': 0.8271251193887297,\n",
       " 'temperature-90': 0.839541547277937,\n",
       " 'temperature-100': 0.887774594078319,\n",
       " 'time': 0.5950334288443171,\n",
       " 'method': 0.7885546170636804,\n",
       " 'pressure': 0.774116523400191}"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "metric_output['gpt4-0'].accuracy_task()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "name_dict = {\n",
    "    'method': 'Synthesis\\nmethod',\n",
    "    'solvent': 'Solvent',\n",
    "    'temperature': 'Temp',\n",
    "    'time': 'Time',\n",
    "    'pressure': 'Pressure',\n",
    "    #'cooling': 'cooling',\n",
    "    #'washing': 'washing',\n",
    "    #'filtration': 'filtration',\n",
    "    #'drying': 'drying',\n",
    "\n",
    "\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWEAAADrCAYAAAC4oyfdAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAlgElEQVR4nO3deVyNef8/8Fc7pbImS4ttyJIUklBokhDqtt+WLDORoWHcJgYRv8yYhrEMhlGyDMaM7bYPNYTGMpYxlilERCIqUeqcz/cPv849B53OlU5Hp9fz8TiPh67rnM95fyovH9e5ruutJ4QQICIirdDXdgFERBUZQ5iISIsYwkREWsQQJiLSIoYwEZEWMYSJiLSIIUxEpEUMYSIiLTLUdgGlRS6XIzU1Febm5tDT09N2OURUgQkhkJ2djbp160JfX/VaV2dCODU1FTY2Ntoug4hIISUlBfXr11f5HJ0JYXNzcwCvJm1hYaHlaoioIsvKyoKNjY0il1TRmRAuPARhYWHBECai94I6h0bL/IM5uVyO0aNHw93dHT4+Pnj48KHS/kmTJqFDhw7o1KkTrl27VtblERGVqTIP4R07dqBy5co4ceIEAgMDERERodh38eJFXLp0CQkJCQgLC8PcuXPLujwiojJV5iF84sQJeHt7AwB8fHwQFxen2Fe3bl1UqlQJ+fn5yM7OhpGRUZHj5OXlISsrS+lBRFTelPkx4aysLMUxW3Nzc2RnZyv2GRkZIS8vD02bNkVmZiZ2795d5DgRERFcKRNRuVfmK2ELCwtF8GZnZ8PS0lKxLyYmBg0bNkRSUhIuX76McePGITc3963jhIaGIjMzU/FISUkpk/qJiEpTmYewm5sbDh06BADYv38/OnbsqNhXtWpVmJubQ19fH9WqVUNBQQEKCgreOo6JiYniTAieEUFE5VWZH47w9/fH/v374e7uDiMjI2zZsgVTp07FqFGjMHToUBw7dgzu7u4oKCjArFmzUKVKFY3Wc2FGsEbH1wSn/7dC2yUQUSnR05Uec1lZWbC0tERmZqakVTFDmIhKm5Q84g18iIi0SGeumCOi8uPLL7/UdgmSTJ8+XWNjcyVMRKRFDGEiIi1iCBMRaRFDmIhIixjCRERaxBAmItIihjARkRYxhImItIghTESkRQxhIiItYggTEWkRQ5iISItKHMLp6eklep2qbsuHDx+Gp6cnPD090alTJxgbG+P+/fslLZGI6L0nKYSfP3+OCRMmwMzMDPb29khMTISjoyNu3Lih9hiqui1/+OGHiIuLQ1xcHLp3746IiAjUqVNHSolEROWKpBCePHkyMjIycP78eRgbG6NBgwbw9vZGUFCQ2mOo6rZc6ObNmzhw4ABCQkKKHIfdlolIF0i6n/CePXtw8+ZNmJqaQk9PD4aGhoiIiICVlZXaY6jqtlzom2++wbRp02BgYFDkOOy2TES6QNJK2MzMTOkYLgCkpaWhWrVqao+hqtsyAMhkMvz666/o27evynHYbZmIdIGkEJ44cSJ8fHzwww8/oKCgANu3b0f//v0lHY5Q1W0ZAP788084OjrCyMhI5TjstkxEukDS4YhPP/0UtWvXRkxMDGxsbLBy5UqMHz8eo0ePVnsMVd2WW7VqhcTERDRs2FDyRIiIyiNJIRwSEoL58+dj6NChJX5DAwMDrFu3TmlbZGSk4s8DBgzAgAEDSjw+KUu7fkDbJUhSu6mPtksgKlOSDkds3rwZhobsDUpEVFokJWqvXr3g5eWFPn36wNraGnp6eop9I0aMKPXiiIh0naQQTk5OhpGREQ4cUP4vrp6eHkOYiKgEJIVwbGyspuogIqqQJB0TlslkCA8PxwcffABTU1PY29sjNDQU+fn5mqqPiEinSVoJz5o1C0eOHMHy5cthZ2eHmzdvIiwsDAUFBVi0aJGmaiQi0lmSQnjjxo04c+YMateuDQBo2rQpnJyc4OTkxBAmIioBSYcj8vLyYGZmprTNzMxM6SwJIiJSn6QQ9vPzw/Dhw3Hjxg3k5+cjKSkJI0eORK9evTRVHxGRTpMUwpGRkTA2NoaDgwMqVaqEVq1awdLSEosXL9ZUfUREOk3SMWELCwssX74cUVFRyMrKQkZGBmrWrMmb5xARlZCklfCOHTvQqFEjXL9+HdbW1jh48CCaN2+Ow4cPa6o+IiKdJimEp0+fjgMHDqBNmzYAXt1VbdeuXZg8ebJGiiMi0nWSQvjBgwdwdXVV2ubq6ooHDx6UalFERBWFpBB2c3PDzJkzFVfI5efnY86cOXBzc1N7DFXdlgFg7dq16NChA1xcXPD9999LKY+IqNyRFMLff/89jhw5AnNzc9SrVw9VqlTBb7/9htWrV6s9hqpuy4mJiYiOjsaxY8dw4sQJtrsnIp0n6ewIOzs7nDlzBrdu3UJaWhrq1asHGxsbSW/4erflhQsXKvYdPXoUzs7OGDJkCB4/fqy073V5eXnIy8tTfM1uy0RUHqm9En748CEuX74MAGjQoAEuXbqEr7766o3bWhZHVbfl9PR0xMfHIyYmBlFRUQgMDIQQ4q3jREREwNLSUvGQ+o8BEdH7QK0QPnHiBBo1aoQNGzYAeHUjn1mzZqFy5coIDg7G5s2b1X5DVd2Wa9SoAQ8PD5iZmaFBgwawsLBAenr6W8dht2Ui0gVqHY744osvsGTJEowZMwYFBQVYvnw5Vq9ejYEDB2LgwIEYM2aM2n3nCrst+/n5vdFtuWPHjli9ejXy8/ORmZmJJ0+eoEaNGm8dx8TEBCYmJmq9J1F581Hk79ouQbLvp7oW/yR6g1ohfP78eRw5cgQAcO7cOeTk5MDX1xcA4OzsjJs3b6r9hqq6Lbdu3RrDhg2Dm5sbhBBYvHgxDAwMSjAtIqLyQXLXztjYWDg7O6NKlSoAgGfPnklakRbXbXnatGmYNm2a1LKIiMoltY4Jd+zYEStXrsSjR4+wfv16BAQEKPYtWbIE7u7uGiuQiEiXqbUSjoyMhK+vLyZNmoROnTrhk08+AQA4Ojri/v37OHbsmEaLJCLSVWqFsIODA27cuIHHjx+jVq1aiu0zZ86El5dXkR+eERGRamofE9bX11cKYAAYNGhQqRdERFSRSLpsmYiIShdDmIhIixjCRERaJOk84SdPnmD16tVISkqCXC5X2vf6ub9ERFQ8SSE8ZMgQpKenw9fXF4aGkq/zICKi10hK0lOnTuHOnTtKN90hIqKSk3RMuEmTJnj8+LGmaiEiqnAkrYQ9PDzQuXNn+Pv7v3HO8OzZs0u1MCKiikBSCGdkZMDb2xvPnj3Ds2fPFNv19PRKvTAioopAUghHRUVpqg4iogpJ0jFhmUyG8PBwfPDBBzA1NYW9vT1CQ0MV3ZfVUVy3ZS8vL3h4eMDT0xNjx46VUh4RUbkjaSU8a9YsHDlyBMuXL4ednR1u3ryJsLAwFBQUYNGiRWqN8c9uy1u3bkVERAQWL16s2J+eno6LFy9KmwURUTklaSW8ceNG7N69G97e3mjatCl69uyJnTt3IiYmRu0xXu+2HBcXp9iXnJyMrKws9OjRA127dsXp06ellEdEVO5IWgnn5eXBzMxMaZuZmZmkD+ZUdVsWQmDq1KmYMGECbty4gd69e+PatWtvHZ8t74lIF0haCfv5+WH48OG4ceMG8vPzkZSUhJEjR6JXr15qj6Gq23K9evUwevRo6Ovro0mTJrC0tMSjR4/eOg5b3hORLpC0Eo6MjMS4cePg4OAAmUwGIyMjDB48WOmYbnFUdVv+73//i59++gk//vgjUlNT8fz5c9SsWfOt44SGhmLKlCmKr7OyshjEFUzwvlHaLkGSFb7R2i6B3kOSQtjCwgJbt25Fbm4unj59CisrK+jrS7sRm6puy/369cPBgwfRsWNHGBgYYM2aNUUe6mDLeyLSBWqF8IQJE/Ddd98hMDCwyFBU9y5qxXVbXr16tVrjEBHpArVCuPC/+fb29pqshYiowlErhENDQwEAzZs3x4ABA97Yv3bt2tKtioiogig2hB8/foy//voLADBq1ChYW1tDCKHYn5WVhU8//ZRXtxERlUCxIVy5cmVMmTIFjx8/Rm5uLkaMGKG038TEBJ9//rnGCiQi0mXFhrCpqSnOnj0LABgxYoSkq+OIiEg1SaeoxcTEIDExEQ8ePFAcksjPz8fVq1cxceJEjRRIRKTLJIXwjBkzEBkZCXNzcwghIIRAZmYmunXrxhAmIioBSVdarF27FgkJCfj555/Rs2dPZGRkYPbs2ahbt66m6iMi0mmSVsIFBQVo06YNMjIycObMGQDA559/zvOHiYhKSHKjz/j4eFSvXh05OTlITU1FdnY2Xrx4oan6iIh0mqSV8Jw5c9C7d29cvHgRkydPhouLC4yMjBAQEKCp+oiIdJqkEPb19cW9e/dgamqKadOmoVOnTnj69Cl8fHw0VR8RkU5TK4SPHTtW5D4zMzMcP34cXbp0KbWiiIgqCrVCeOTIkQBeNem8e/cuatSogfr16+PBgwdIS0uDo6Mjzp8/r9FCiYh0kVohfOvWLQDA+PHjYW9vj2nTpinuI/ztt9/i999/11yFREQ6TNLZEZs2bcJnn32mdCP34OBg7NmzR+0ximt5D7zquFy/fn0kJydLKY+IqNyRFMINGzZEdHS00rYVK1agWbNmao/xz5b3gYGBiIiIUNovl8sxceJEmJqaSimNiKhcknR2xKpVq9C/f38sWLAAdevWxZ07d6Cvry9pJfx6y/uFCxcq7Z87dy6GDRuGtLQ0leOw2zIR6QJJIdyhQwfcunULJ0+eRFpaGqytreHu7g5jY2O1x1DV8v7gwYN48eIF/Pz88M0336gcJyIiAnPnzpVSPhHRe0dal04AFy5cQGpqKvLz85GSkoItW7ZIur2lqpb369evx8mTJ+Hp6YkLFy5g8ODByMzMfOs4oaGhyMzMVDxSUlKkToWISOskrYSDg4OxYcMGtG7dGoaG/3upnp7eGzd7L4qqlvebN29W/NnT0xPR0dFKIf1P7LZMRLpAUghv27YNp06dQosWLUr8hqpa3rdq1arE4xIRlUeSQrhKlSqwtbV9pzcsruV9obi4uHd6HyKi8kBSCI8fPx7+/v4ICgpCrVq1lPbxsmUiIukkhfDKlSsBAJ999pnSdj09Pdy8ebP0qiIiqiAkhXDh5ctERFQ6JJ+idubMGQQHB6N///54/PgxIiMjFU0/iYhIGkkhvHHjRvTr1w9Vq1bF0aNHUVBQgHXr1mH69Omaqo+ISKdJCuHw8HAcOHAACxYsgL6+PmrXro1Dhw5JuliDiIj+R1IIZ2RkwMHBAcCrD+MAwMrKCjKZrPQrIyKqACSFcLdu3TBlyhTk5uYqtoWHh8PDw6PUCyMiqggkhfDy5ctx7do1WFhYIDMzE5aWljh27BiWLVumqfqIiHSapFPUatWqhUOHDuHBgwdISUmBtbU1bGxsNFUbEZHOkxTCubm52Lp1K1JSUiCXy5X2zZ49u1QLIyKqCCSFsL+/P27duoX27dsrtTgq/JCOiIikkRTC8fHxuHfvHszNzTVVDxFRhSLpgzkXFxfcvn1bU7UQEVU4klbCCxcuRJcuXdC1a9c3brb++u0piyKXyzF27Fhcv34d5ubmiImJgZWVlWJ/SEgITp8+DUNDQ0RHR6Nhw4ZSSiQiKlckrYSDg4Ph7OyMFi1awM7OTumhLlXdluPj43H37l2cPHkS8+bN4+XQRKTzJK2Er1+/jszMTKUP5aRS1W25U6dO6NChAwAgJSUF1apVK3IcdlsmIl0gKU19fHzw66+/vtMbquq2DACGhoYICgrCxIkTMWDAgCLHiYiIgKWlpeLB85WJqDyStBKWy+Xo1asXmjdvjurVqyudmnb06FG1xlDVbbnQqlWrEB4eDjc3N1y8eBFmZmZvPCc0NBRTpkxRfJ2VlcUgJqJyR1II+/n5wc/P753eUFW35b179yI+Ph4RERGoXLky9PX1izz0wW7LRKQLJIXwyJEj3/kNVXVb/vDDD7F161Z07twZMpkMX375JSpXrvzO70lE9L6SFMK//PILpk6dipSUlDe6aah7O8viui3z3sREVJFICuFPPvkEs2fPhre39zudIUFERK9ICmGZTIYxY8bA0FDSy4iIqAiS0nT27NmYMGECJk2apDjNrJCtrW2pFkZEVBFICuFnz55h3bp1WLt2rdJ2PT09tjgiIioBSQd2IyIicPjwYRQUFEAulyseDGAiopKRFMKWlpbo0KEDP5QjIiolkg5HhISEoH///vj444/fuGKuS5cupV4cEZGukxTC3377LQAoXS4MvDomfPPmzdKrioiogpAUwrdu3dJUHUREFZLkE36PHz+ODRs24O7du7CyssLgwYPh4+OjidqIiHSepE/YNm3ahP79+6NmzZro27cvrK2tMWzYMLW7ahARkTJJK+EFCxZg//79aNeunWKbv78/hg4ditGjR5d6cUREuk7SSvj+/fto06aN0jZnZ2c8evSoVIsiIqooJIVw+/bt8fXXXyttW7RoEdq2bVuqRRERVRSSDkcsXboU3t7e+O6772BjY4Pbt2/DzMwMe/bsUXsMVd2WhRAIDg7GpUuXkJeXh1mzZr3zTeSJiN5nkkK4adOmSExMxPHjx5Geno769eujQ4cOku6q9s9uy1u3bkVERAQWL14MANi/fz+ePXuG+Ph4ZGRkoH379gxhItJpkg5HXLlyBa6urrC0tMTgwYOxc+dOuLm5SbpQ4/Vuy3FxcYp9Xbt2xbJlywC8WhUbGBgUOU5eXh6ysrKUHkRE5Y2kEB43bhyGDRsGJycnAMDChQsxePBgjB07Vu0xVHVbrly5MiwtLZGTk4OBAwdi5syZRY7DbstEpAskhfDly5fx2WefKQ4/GBoaYsqUKTh//rzaYxTXbTktLQ1eXl4YNGgQRowYUeQ4oaGhyMzMVDxSUlKkTIWI6L0gKYQbNGiAXbt2KW3bt28fGjZsqPYYhd2WAbzRbTk7OxsffvghZs6ciY8++kjlOCYmJrCwsFB6EBGVN5I+mPv6668REBCANm3aoF69erh37x7+/PNP7Ny5U+0xVHVb3rNnD1JTU/H1118rToU7cuSIymPDRETlmaQQ9vLywt9//419+/YhLS0NPj4+6NmzJ2rWrKn2GKq6Lbdq1QozZsyQUhIRUbkm+e7sVapUQZUqVWBsbIyAgAAkJydroCwioopBUgj/8ccfaNy4MZYsWYI5c+YgLS0NXbt2xYYNGzRVHxGRTpMUwsHBwVi2bBlOnDgBQ0NDNGjQAAcOHMC8efM0VR8RkU6TFMLXrl2Dv78/AChaG7m7uyM9Pb30KyMiqgAkhXCLFi2wbds2pW179+5F8+bNS7UoIqKKQvINfHr27IkVK1YgJycHvXv3xtmzZ7F7925N1UdEpNMkhbCzszMSExOxb98++Pn5wdraGjExMahevbqm6iMi0mlqh7AQAhkZGahRowYGDx6s2J6Xl4fPP/8cCxcu1EiBRES6TK1jwvHx8ahfvz6srKzg5OSE+/fvA3jV9LNly5Y8RY2IqITUCuGQkBAMHDgQ58+fh5OTE2bNmoXVq1fDy8sL3t7euHr1qqbrJCLSSWodjrh+/TpOnjwJY2NjLF++HLa2tjh8+DAOHjwIT09PDZdIRKS71AphPT09GBsbA3h12fKLFy8QGxuL1q1ba7Q4IiJdJ/neEQBQqVIlBjARUSlQayUshEBKSgqEEG/9GgBsbW01UyERkQ5TK4RzcnJgb2+vFLp2dnaKP+vp6UEmk6n1hqq6LRc6ffo0Zs2ahYMHD6o1JhFReaXW4Qi5XA6ZTAa5XP7Wh7oBDCh3Ww4MDERERITS/iVLlmDMmDHIy8uTNhMionKoRMeE34WqbsvAqxX2L7/8Uuw47LZMRLqgzENYVbdlAOjfvz+MjIyKHYfdlolIF5R5CBfXbVld7LZMRLqgzENYVbdlKdhtmYh0QZmHsL+/P54/fw53d3esWrUKM2fOxNSpU/Hnn3+WdSlERFon6VaWpUFVt+VC9vb2b3xgR0Ski8p8JUxERP/DECYi0iKGMBGRFjGEiYi0iCFMRKRFDGEiIi1iCBMRaRFDmIhIixjCRERaxBAmItIihjARkRYxhImItIghTESkRQxhIiItKvMQlsvlGD16NNzd3eHj44OHDx8q7Z85cyZcXV3RpUsXJCYmlnV5RERlqsxDWFW35XPnzuHChQv4/fffsWjRIvznP/8p6/KIiMrUe9Vt+Z/7XF1dcfHixbIuj4ioTJV5Zw1V3ZazsrJQr149xddCiCLHycvLQ15enuLrzMxMxRhSPMt7Ken57wMpc8x+lqPBSkpfZQlze/m8fP3spPzcXuaWr58bIG1+ubm5Gqyk9EnNlcLnq8qwQmUewqq6Lf9zHwDo6xe9UI+IiMDcuXPf2G5jY1OK1b6nvlmr7QqoBNbiR22XoFHrv9B2BZoTFhZWotep01G+zEO4sNuyn5/fG92W3dzcMG/ePEyaNAkJCQlo3rx5keOEhoZiypQpiq/lcjkyMjJQo0YN6OnpaXQOxcnKyoKNjQ1SUlJ0sgu0Ls9Pl+cG6Pb83qe5CSGQnZ2NunXrFvvcMg9hf39/7N+/H+7u7jAyMsKWLVswdepUjBo1Cu3atYOjoyM6dOgAAIiKiipyHBMTE5iYmChtq1q1qiZLl8zCwkLrvwyapMvz0+W5Abo9v/dlbsWtgAvpCXUOWpAkWVlZsLS0RGZm5nvxy1DadHl+ujw3QLfnV17nxos1iIi0iCGsASYmJpgzZ84bh0t0hS7PT5fnBuj2/Mrr3Hg4gohIi7gSJiLSIoYwEZEWMYSJiLSowofw9u3b4eLigtatW6NVq1ZYtGhRicYJDAzE7du3AQD29vZITk5+59qcnJzeeYy3kTpnT09PpXt8vKvMzEz069ev1MZTZezYsXByckLz5s1hbGwMJycnODk5YcWKFWXy/mWhqDnq6ekhNTVV2+UVKTk5WVFvmzZt0KpVK3Tq1AmXL1/WdmllS1Rgd+/eFba2tuLRo0dCCCGys7OFs7Oz2Llzp+Sx7OzsxK1bt9748/umJHP28PAQsbGxpVbDrVu3hJ2dXamN976+Z1krb3N8W73Lly8XTk5O2ilISyr0SvjRo0fIz8/Hs2fPAABVqlTB+vXrUbVqVbRv317xvO3bt2PIkCGIi4uDl5cXAgIC0Lx5c3h7eyMjIwMLFixAamoqfH19FfdHXrBgAZydndGoUSPs3bsXAJCeng5/f3+4uLjAxcUFe/bsAQAkJCSgffv2aNeuHTp37ozr168DgOLy66L2l+acW7RogYSEBLi6usLR0RHdu3dHUlKS0msDAgKwZcsWxdceHh6IjY0tcl5hYWEYN24cunXrhoYNG2LixIkAgODgYKSmpsLPz6/E83gXN27cgLe3N5ydneHm5oaTJ08CAEaNGoUJEyagTZs2sLW1xcaNGxEQEIBGjRohJCQEABAdHY3evXujS5cuaNy4MSZPnqzWTVq0ofB/ZNHR0QgICIC7uztsbW0xb948hISEwNHRER4eHnjx4gUAYOPGjXBxcYGTkxOGDRumdB+XstKtWzf8/fff8PT0RP/+/dGsWTMkJCTg0KFDaN++PZydndGnTx/FCn/evHlwdHSEs7MzPv74YwBAUlIS3N3d0bZtW7i6uip+vv/8H2pycjLs7e0BvPq59+7dGw4ODti+fTvOnTuHzp07w9nZGd26dcO1a9c0O2lt/yugbUFBQcLQ0FC0a9dO/Oc//xHnz58XcrlcNG7cWFy9elUIIUSvXr3EoUOHRGxsrDAzMxO3b98WQgjh5+cnli5dKoR4cyW8cOFCIYQQu3btEm3bthVCCDFkyBDx888/CyGESE9PF40aNRJpaWmiX79+Yvfu3UIIIbZs2SKio6OFEEIU/niK2l+ac87LyxO2trbi1KlTQgghtm3bpqi7cCW8c+dO0bdvXyGEECkpKcLe3l7I5fIi5zVnzhzRtm1bkZubK7Kzs0XdunXFpUuXtL4Sdnd3F2fOnBFCCJGUlCTs7e1Ffn6+GDlypPDz8xNCCBEdHS0sLS1FWlqayMrKEubm5uLJkyciKipK1KpVS9y/f1/k5eUJNzc3sW3btjKdS1Fe/74W/k5GRUWJ+vXri8zMTJGcnCwAiAMHDgghhPD09BQ7d+4UV65cEe7u7uL58+dCCCHmz58vpk6dWqb1ymQy8fnnn4sePXoIDw8PMXPmTCHEq9+p1q1bi8ePHwshhNi4caMICAgQT58+FVZWVqKgoEDIZDIRFBQk7ty5I0JCQhR/L2NjY8WXX36p9P14/b1Hjhwphg0bJoQQ4uXLl8LR0VHxvPj4eOHi4qLR70OZ3zvifbNy5Up88cUXOHToEA4ePAg3NzfExMRg9OjRiImJwaRJk3D16lV0794dx44dQ8uWLWFrawvg1THbjIyMt44bEBAAAGjVqhUePXoEADh06BD++usvzJs3DwCQn5+Pq1evws/PD2PHjkWfPn3Qu3dv/Otf/1Iaq7j9pTHnGTNmoFq1aor7dgwYMAAfffSR4hahAODr64vg4GBkZmbixx9/xJAhQ6Cnp1fkvACge/fuivt8NG7cGBkZGTA3N3+n+t/Fs2fPcPr0aYwdO1axLT8/H3fu3AEA9OrVCwBgZ2eHli1bwsrKCgBQvXp1PH36FADQp08fWFtbAwAGDx6M3377DQMGDCjDWUjXuXNnpXsqdO/eHcCreT558gRHjhxBYmIi3NzcALz6njRs2FDjdaWmpio++8jLy0PLli2xZs0aDB8+XHFzr4SEBNy+fRvdunUD8OpmXfr6+rC0tETz5s3Rrl079OnTBxMnToSNjQ18fHzw73//GwkJCfD19cWkSZOKraPwva5fv46kpCSlzyzS09Px8uVLGBsbl+7k/78KHcJ79+5FTk4OBg4ciMDAQAQGBmLNmjWIjo7GmjVr0LlzZ9SuXRvDhg1T3FazUqVKitfr6ekV+V9RQ0PDN54jk8kQGxuL6tWrAwDu37+PWrVqwcPDA927d8fevXuxePFi7N27F2vWrFGMFRgYqHJ/acx58+bNbzxXCIGCggLF10ZGRujfvz927tyJLVu2YOPGjSrnFRsbq/b3q6zIZDJUqlQJFy5cUGy7d+8e6tSpAwBKf9EKf4av++d2uVwOAwMDzRRbil4PkNfnJpPJMGjQICxduhQAkJOTo3S/bk2pW7eu0s/in0xNTRW1de7cGbt37wYAvHz5Ek+ePAEAHD16FCdPnsSBAwfQo0cPbNq0CT169MCVK1ewd+9ebN26FdHR0Th8+LDS79/Lly+LfK9GjRopahJC4N69exoLYKCCnx1hamqKGTNmKM5qEELgypUrcHR0RN26deHg4IDIyEgEBgYWO5ahoaFSYL1Nt27d8N133wEAEhMT0aJFC2RkZMDX1xfXr1/H+PHjER4ejj/++EPpdcXtl6KoOXfo0AEZGRlISEgAAGzbtg3169dHjRo1lF4/YsQILF26FPr6+nBwcFA5r6Ko873SFEtLSzRp0kTxD0h8fDxcXFwk1XPgwAE8ffoUubm5+PHHHxXdYMozT09P7NixA2lpaQCATz/9FOHh4Vqu6hVXV1ecOnUKf//9NwBg0aJFCAoKQnJyMlq3bg1nZ2eEh4fD29sbly5dwvjx47Fr1y6MGjUKy5cvV/x9qVmzpqJbz08//fTW92rWrBkyMjJw7NgxAMDmzZvRp08fjc6vQq+Eu3btilmzZqFXr17Iz88HAHh7eytu4Dx48GDk5OSgQYMGxY7Vt29f+Pr6Yt++fUU+Z9myZQgKCoKjoyPkcjl++OEHWFlZYc6cOZgwYQKmT58OIyMjfPPNN0qvK25/ac3Zz88PkydPRk5ODqpWrYpt27a98fp27drhxYsXCAoKKnZeRalTpw7s7e3RuXNnHD9+vMRzKalNmzZh/Pjx+Oqrr2BgYIDt27dLWunUqVMHvXv3xsOHDzF06FDFIYzyrHXr1ggLC4OXlxfkcjkcHBze6fesNFlbW2PdunUYNGgQCgoKULt2bWzYsAF16tTBoEGD4OzsDFNTU9jZ2WHUqFFIS0vDyJEjsWLFChgYGGDVqlUAgPnz52PixImYN29ekYf0TExM8NNPPyEkJAQvXryAmZkZNm3apNH58d4RRSgoKMCYMWPQo0cPDB06VNvl0HsiOjoacXFxiI6O1nYppCMq9OGIogghUKdOHTx//hyDBg3SdjlEpMO4EiYi0iKuhEvZnDlzFMc53/Vy39K+XJiI3j8M4VL222+/QSaTabsMIionGMJvERcXh27dusHb2xsNGjTA+PHjMX/+fLRt2xZt2rTB/fv333oZZVRUFM6ePYuxY8cqzjOMioqCi4sL7O3t8cMPPwAAnj9/jmHDhqFly5ZwdHRETEwMgFcnqw8fPhzNmjWDr6+v4iIPItJdFfoUNVVOnz6NK1euoGbNmrCyskJkZCTOnj2LwMBAfP/999ixYweOHj2K6tWrY9OmTZg0aRK2b9+O9evXIywsTHEVkKmpKc6dO4dLly6he/fuGDNmDMLCwlCtWjVcvnwZjx49Qvv27eHk5IRDhw5BJpPh6tWrSEpKgqOjo3a/CUSkcQzhIjg6OiouT65Zs6bSZZ579ux562WUb/O2y5ePHj2KtWvXKsbu27cv4uLiEBcXh48++gh6enpo0qSJ4lJKItJdDOEiqLrMU9VllK/75+XLheRyudJzhBDIz89/47JeIyOjd5sEEb33eEy4BIq6jBJQ//LlwpXwo0ePsGPHDnTp0gVeXl7YsGED5HI5UlJSFLfgIyLdxZVwCRR1GSXw6i5cQUFBiIqKKvL1s2fPxoQJE9CyZUvIZDKEhoaiXbt2cHJywuXLl+Hg4AA7Ozu0aNGirKZERFrCizWIiLSIhyOIiLSIIUxEpEUMYSIiLWIIExFpEUOYiEiLGMJERFrEECYi0iKGMBGRFjGEiYi0iCFMRKRFDGEiIi36P+1ejhMyNcYVAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 354.331x236.221 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model = 'gpt4-0'\n",
    "mm = 0.0393701\n",
    "#color=['#CF796A',  '#658CC8', '#CF796A',  '#658CC8', '#CF796A',  '#658CC8', '#CF796A',  '#658CC8',  '#999999', '#999999']\n",
    "# color = ['#999999'] * len(name_dict)\n",
    "color = ['#CF796A', '#E8D8B7', '#6AB55F', '#658CC8', '#888888']\n",
    "\n",
    "plt.rcParams['font.family'] = 'arial'\n",
    "plt.rcParams['font.size'] = 7\n",
    "\n",
    "fig, ax = plt.subplots(1, 1, figsize=(90* mm, 60* mm))\n",
    "\n",
    "value_dict = metric_output[model].accuracy_task()\n",
    "\n",
    "for i, key in enumerate(name_dict.keys()):\n",
    "    value = value_dict[key]\n",
    "    #value = result_dict[key]\n",
    "    #sns.boxplot(x=i, y=value, color=color[i], width=0.5, linecolor='#252525', linewidth=0.75, fliersize=1.5)\n",
    "    plt.bar(x=i, height=value, color=color[i])\n",
    "\n",
    "plt.xticks(range(len(name_dict)), name_dict.values(), fontsize=8)\n",
    "#plt.xlabel('LLM Model', fontsize=7)\n",
    "plt.ylabel('Recommendation Score', fontsize=9)\n",
    "# plt.legend(['GPT-4o', 'GPT-3.5'], loc='upper right')\n",
    "plt.tight_layout()\n",
    "\n",
    "plt.savefig('feature_importance.eps', bbox_inches='tight')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "llmminer",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
